/*
 * This file is part of the Try! Engine project.
 *
 * Copyright 2010-2011 Emanuele Bertoldi. All rights reserved.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * You should have received a copy of the modified BSD License along with this
 * program. If not, see <http://www.opensource.org/licenses/bsd-license.php>
 */

#include "audiosource.h"
#include "audiomanager.h"
#include <object.h>

using namespace Try;

PropertyName AudioSource::name = "try.audio.audiosource";

MessageName AudioSource::Msg::started = "started";
MessageName AudioSource::Msg::stopped = "stopped";
MessageName AudioSource::Msg::paused = "paused";
MessageName AudioSource::Msg::gainChanged = "gainChanged";
MessageName AudioSource::Msg::pitchChanged = "pitchChanged";
MessageName AudioSource::Msg::updated = "updated";

AudioSource::AudioSource(
    Object* owner,
    const String& filename,
    const Vector3& pos,
    const Vector3& dir,
    const Vector3& vel
    )
    :   Property(AudioSource::name, owner),
        m_source(0)
{
    m_source = audio->load(filename);

    this->setPosition(pos);
    this->setDirection(dir);
    this->setVelocity(vel);
}

AudioSource::~AudioSource()
{
    audio->release(m_source);
}

bool AudioSource::isPlaying() const
{
    return audio->isPlaying(m_source);
}

float AudioSource::gain() const
{
    return audio->gain(m_source);
}

float AudioSource::pitch() const
{
    return audio->pitch(m_source);
}

Vector3 AudioSource::position() const
{
    return audio->position(m_source);
}

Vector3 AudioSource::direction() const
{
    return audio->direction(m_source);
}

Vector3 AudioSource::velocity() const
{
    return audio->velocity(m_source);
}

bool AudioSource::play(bool loop, bool force_restart)
{
    if (audio->play(m_source, loop, force_restart))
    {
        this->notifyMessage(Message(AudioSource::Msg::started));
        return true;
    }

    return false;
}

bool AudioSource::stop()
{
    if (audio->stop(m_source))
    {
        this->notifyMessage(Message(AudioSource::Msg::stopped));
        return true;
    }

    return false;
}

bool AudioSource::pause()
{
    if (audio->pause(m_source))
    {
        this->notifyMessage(Message(AudioSource::Msg::paused));
        return true;
    }

    return false;
}

bool AudioSource::setGain(float gain)
{
    if (audio->setGain(m_source, gain))
    {
        this->notifyMessage(Message(AudioSource::Msg::gainChanged, gain));
        return true;
    }

    return false;
}

bool AudioSource::setPitch(float pitch)
{
    if (audio->setPitch(m_source, pitch))
    {
        this->notifyMessage(Message(AudioSource::Msg::pitchChanged, pitch));
        return true;
    }

    return false;
}

bool AudioSource::setPosition(const Vector3& pos)
{
    if (audio->setPosition(m_source, pos))
    {
        this->notifyUpdate();
        return true;
    }

    return false;
}

bool AudioSource::setDirection(const Vector3& dir)
{
    if (audio->setDirection(m_source, dir))
    {
        this->notifyUpdate();
        return true;
    }

    return false;
}

bool AudioSource::setVelocity(const Vector3& vel)
{
    if (audio->setVelocity(m_source, vel))
    {
        this->notifyUpdate();
        return true;
    }

    return false;
}

Property* AudioSource::copy(Object* owner) const
{
    return 0;
}

void AudioSource::notifyUpdate()
{
    this->notifyMessage(Message(AudioSource::Msg::updated, this->position(), this->direction(), this->velocity()));
}
